//
//  NIBaseObject.m
//  AIWAYS
//
//  Created by Marx on 2018/7/31.
//  Copyright © 2018年 wlq. All rights reserved.
//

#import "NIBaseObject.h"

@implementation NIBaseObject

/**
 拼接请求字典，key为requestObject对应的字段，value为拼接的请求字典对应的key
 例如1：
 return @{
 @"AA":@"aa",
 @"BB":@"bb",
 };
 其中AA、BB为requestObject 中的字段名称，
 aa、bb为转换后字典中的key，转换后的结果为{@"aa":self.AA;@"bb":self.BB}
 例如2：
 return @{
 @"AA":@"aa.bb",
 @"BB":@"aa.cc",
 };
 其中AA、BB为requestObject 中的字段名称，
 转换后的结果为{@"aa":{@"cc":self.AA;@"bb":self.BB}}
 @return 字典
 */
+ (NSDictionary *)modelCustomPropertyMapper{
    return nil;
}

- (NSDictionary *)getDicFromObject{
    //最终的请求内容
    NSMutableDictionary *weCloudrequestParamsDic = [[NSMutableDictionary alloc] initWithCapacity:0];
    //请求参数对应表
    NSDictionary *paramsMapperDic = [[self class] modelCustomPropertyMapper];
    NSArray *keyArray = paramsMapperDic.allKeys;//mapper表中的key数组
    NSArray *valueArray = paramsMapperDic.allValues;//mapper表中的value数组
    NSString *key;
    NSString *value;
    for (int i= 0; i < keyArray.count; i++) {//遍历mapper表中的所有key
        key = [keyArray objectAtIndex:i];//实例中对应的key
        value = [valueArray objectAtIndex:i];//mapper表中的value，可能存是一个属性名称，也可能是以.分割的多个属性的名称，
        NSArray *dicKeyArray = [value componentsSeparatedByString:@"."];//将mapper表中的value，以.分割成多个属性名称
        NSMutableArray *tempDicArray = [NSMutableArray arrayWithCapacity:0];//存储临时的字典
        for (int i = 0;i<dicKeyArray.count;i++) {
            if (i < dicKeyArray.count - 1) {
                if (i == 0) {//不是单层结构，第一层，获取或创建字典
                    NSMutableDictionary *dic = (NSMutableDictionary *)[weCloudrequestParamsDic objectForKey:[dicKeyArray objectAtIndex:0]];
                    if (dic == nil) {
                        dic = [NSMutableDictionary dictionaryWithCapacity:0];
                        [weCloudrequestParamsDic setObject:dic forKey:[dicKeyArray objectAtIndex:0]];
                    }
                    [tempDicArray addObject:dic];
                }
                else
                {
                    //不是单层结构，不是第一层，获取或创建字典
                    NSMutableDictionary *dic = (NSMutableDictionary *)[tempDicArray objectAtIndex:i-1];
                    NSMutableDictionary *dic2 = (NSMutableDictionary *)[dic objectForKey:[dicKeyArray objectAtIndex:i]];
                    if (dic2 == nil) {
                        dic2 = [NSMutableDictionary dictionaryWithCapacity:0];
                        [dic setObject:dic2 forKey:[dicKeyArray objectAtIndex:i]];
                    }
                    [tempDicArray addObject:dic2];
                }
                
                
            }
            else
            {
                //单层结构，或最后一层
                if ([self valueForKey:key]) {
                    //判断如果是数组类型的
                    if ([[self valueForKey:key] isKindOfClass:[NSArray class]]) {
                        NSArray * objectArray = (NSArray *)[self valueForKey:key];
                        NSMutableArray *tempDicArray = [[NSMutableArray alloc]initWithCapacity:0];
                        for (int i = 0; i < objectArray.count; i ++ ) {
                            //遍历数组，将对象转换成字典
                            NSDictionary *tempDic = [[objectArray objectAtIndex:i] getDicFromObject];
                            if (tempDic) {
                                
                                [tempDicArray addObject:tempDic];
                            }
                            
                        }
                        if (dicKeyArray.count == 1) {
                            //单层结构，直接赋值
                            [weCloudrequestParamsDic setObject:tempDicArray forKey:[dicKeyArray objectAtIndex:i]];
                        }
                        else
                        {
                            //多层结构，将转换后的数组，set到上层字典中
                            NSMutableDictionary *dic = (NSMutableDictionary *)[tempDicArray objectAtIndex:i-1];
                            [dic setObject:tempDicArray forKey:[dicKeyArray objectAtIndex:i]];
                        }
                    }
                    else if ([[self valueForKey:key] isKindOfClass:[NIBaseObject class]]) {
                        //判断如果是对象类型
                        NSDictionary *tempDic = [[self valueForKey:key] getDicFromObject];
                        if (dicKeyArray.count == 1) {
                            //单层结构，直接赋值
                            [weCloudrequestParamsDic setObject:tempDic forKey:[dicKeyArray objectAtIndex:i]];
                        }
                        else
                        {
                            //多层结构，将转换后的数组，set到上层字典中
                            NSMutableDictionary *dic = (NSMutableDictionary *)[tempDicArray objectAtIndex:i-1];
                            [dic setObject:tempDic forKey:[dicKeyArray objectAtIndex:i]];
                        }
                    }
                    else
                    {
                        if (dicKeyArray.count == 1) {
                            
                            [weCloudrequestParamsDic setObject:[self valueForKey:key] forKey:value];
                        }
                        else
                        {
                            
                            NSMutableDictionary *dic = (NSMutableDictionary *)[tempDicArray objectAtIndex:i-1];
                            [dic setObject:[self valueForKey:key] forKey:[dicKeyArray objectAtIndex:i]];
                        }
                    }
                }
            }
        }
        
        
    }
    return weCloudrequestParamsDic;
    
}



- (NSDictionary *)dictionaryRepresentation {
    unsigned int count = 0;
    //get a list of all properties of this class
    objc_property_t *properties = class_copyPropertyList([self class], &count);
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:count];
    
    NSDictionary *mapDictionary = self.attributeMapDictionary;
    
    for (int i = 0; i < count; i++) {
        NSString *key = [NSString stringWithUTF8String:property_getName(properties[i])];
        id value = [self valueForKey:key];
        //        NSLog(@"key = %@, value = %@, value class = %@, changed Key = %@", key, value, NSStringFromClass([value class]), [mapDictionary objectForKey:key]);
        key = [mapDictionary objectForKey:key];
        //only add it to dictionary if it is not nil
        if (key && value &&(![value isKindOfClass:[NSNull class]])) {
            [dictionary setObject:value forKey:key];
        }
    }
    free(properties);
    return dictionary;
}

- (id)initWithDictionary:(NSDictionary *)attributeDictionary
{
    self = [super init];
    if (self) {
        //建立映射关系
        [self setAttributesDictionary:attributeDictionary];
    }
    
    return self;
}

/**
 初始化映射字典
 
 @return 映射字典
 */
- (NSDictionary *)attributeMapDictionary
{
    if (!_attributeMapDictionary) {
        _attributeMapDictionary = ({
            NSDictionary *mapDictionary = [self getMapDictionary];
            if (mapDictionary == nil) {
                //没有重写映射字典
                unsigned int count = 0;
                //get a list of all properties of this class
                objc_property_t *properties = class_copyPropertyList([self class], &count);
                NSMutableDictionary *temporaryDictionary = [NSMutableDictionary dictionaryWithCapacity:count];
                for (int i = 0; i<count; i++) {
                    NSString *key = [NSString stringWithUTF8String:property_getName(properties[i])];
                    [temporaryDictionary setObject:key forKey:key];
                }
                free(properties);
                mapDictionary = temporaryDictionary;
            }
            mapDictionary;
        });
    }
    return _attributeMapDictionary;
}

//子类可重写此方法建立映射
- (NSDictionary *)getMapDictionary
{
    
    return nil;
}

- (void)setAttributesDictionary:(NSDictionary *)attributesDictionary
{
    //获得映射字典
    NSDictionary *mapDictionary = self.attributeMapDictionary;
    
    NSEnumerator *keyEnumerator = [mapDictionary keyEnumerator];
    id attributeName = nil;
    while ((attributeName = [keyEnumerator nextObject])) {
        //获得属性set方法
        SEL setter = [self _getSetterWithAttributeName:attributeName];
        if ([self respondsToSelector:setter]) {
            //获得映射字典的值，也就是传入字典的键
            NSString *attributeDictionaryKey = [mapDictionary objectForKey:attributeName];
            //获得传入字典的键对应的值，也就是要赋给属性的值
            id attributeDictionaryValue = [attributesDictionary objectForKey:attributeDictionaryKey];
            //            NSLog(@"%@,%@",attributeDictionaryKey,attributeDictionaryValue);
            //为属性赋值
            if ([attributeDictionaryValue isKindOfClass:[NSNull class]]) {
                attributeDictionaryValue = nil;
            }
            [self performSelectorOnMainThread:setter withObject:attributeDictionaryValue waitUntilDone:[NSThread isMainThread]];
        }
    }
}

- (SEL)_getSetterWithAttributeName:(NSString *)attributeName
{
    NSString *firstAlpha = [[attributeName substringToIndex:1] uppercaseString];
    NSString *otherAlpha = [attributeName substringFromIndex:1];
    NSString *setterMethodName = [NSString stringWithFormat:@"set%@%@:", firstAlpha, otherAlpha];
    return NSSelectorFromString(setterMethodName);
}

- (id)copyWithZone:(NSZone *)zone
{
    id model = [[self.class allocWithZone:zone] init];
    [self Convert:model];
    return model;
}

-(void)Convert:(id)obj
{
    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList([self class], &outCount);
    for(i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        NSString *key = [[NSString alloc] initWithUTF8String:property_getName(property) ];
        id value=[self valueForKey:key];
        if (value!=nil) {
            [obj setValue:value forKey:key];
        }
    }
    free(properties);
}

@end
